package towerz.game.level;

import java.util.Vector;
import javax.microedition.lcdui.Image;
import towerz.game.entity.tower.TowerFactory;
import towerz.system.BitmapFont;
import towerz.system.StringManager;

import towerz.system.Utilities;
import towerz.system.xml.XmlNode;
import towerz.system.xml.XmlReaderWriter;

public class Level {
	public class Tutorial {
		public Tutorial(XmlNode xml) {
			//Initialize
			m_X		= Integer.parseInt(xml.getAttribute("x"));
			m_Y		= Integer.parseInt(xml.getAttribute("y"));
			m_ID	= Integer.parseInt(xml.getAttribute("id"));
			m_Lines	= new Vector();
			
			//Get lines
			for (int i = 0; i < xml.getChildren().size(); i++) {
				XmlNode Child = (XmlNode)xml.getChildren().elementAt(i);
				if (Child.getNodeName().equals("lines")) {
					if (Child.getAttribute("language").equals(StringManager.instance().getTag())) {
						//For each child
						for (int j = 0; j < Child.getChildren().size(); j++) {
							m_Lines.addElement(BitmapFont.getFont(BitmapFont.MAIN).renderTransparentText(
								((XmlNode)((XmlNode)Child.getChildren().elementAt(j)).getChildren().elementAt(0)).getNodeValue(), 0x00000000));
						}
					}
				}
			}
		}
		
		//Accessor
		public int getID()	{	return m_ID;	}
		public int getX()	{	return m_X;		}
		public int getY()	{	return m_Y;		}
		public Image[] getLines() {
			//Create from vector
			Image[] Images = new Image[m_Lines.size()];
			for (int i = 0; i < m_Lines.size(); i++) Images[i] = (Image) m_Lines.elementAt(i);
			
			//Return
			return Images;
		}
		
		//Data
		protected int		m_ID;
		protected int		m_X;
		protected int		m_Y;
		protected Vector	m_Lines;
	}
	
	protected Level() {
		//Initialize
		m_Index		= 0;
		m_StartX	= 0;
		m_StartY	= 0;
		m_FinishX	= 0;
		m_FinishY	= 0;
		m_StartGold	= 0;
		m_GoldGoal	= -1;
		m_TimeGoal	= -1;
		m_TowerGoal	= new int[TowerFactory.instance().getTowerNumber()];
		for (int i = 0; i < m_TowerGoal.length; i++) m_TowerGoal[i] = -1;

		//Empty
		m_Map		= null;
		m_Huts		= null;
		m_PathX		= null;
		m_PathY		= null;
		m_Towers	= null;
		m_Waves		= new Vector();
		m_Dialogs	= new Vector();
		m_Tutorials	= new Vector();
	}

	public Level(String file) {
		//Default
		this();
		
		//Temporary data
		String Set 	= null;
		String Map	= null;
		
		//Read XML	
		XmlNode xmlNode = XmlReaderWriter.getInstance().readFromXmlFile(file);
		
		//Get index
		m_Index = Integer.parseInt(xmlNode.getAttribute("index")); 
		
		//For each child
		for(int i=0; i < xmlNode.getChildren().size(); i++) {
			//Get node
			String Tag 		= ((XmlNode)xmlNode.getChildren().elementAt(i)).getNodeName();
			String Value 	= ((XmlNode)((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().elementAt(0)).getNodeValue();
            
			if (Tag.equals("gold"))	m_StartGold	= Integer.parseInt(Value);
            else if (Tag.equals("life"))	m_StartLife	= Integer.parseInt(Value);
            else if (Tag.equals("tileset"))	Set = Value;
            else if (Tag.equals("map"))		Map = Value;
			else if (Tag.equals("start")) {
				//Get point
				String[] point	= Utilities.split(Value, ",");
				m_StartX		= Integer.parseInt(point[0]);
				m_StartY		= Integer.parseInt(point[1]);
			}
			else if (Tag.equals("towers")) {
				//Get tower
				String[] towers	= Utilities.split(Value, ";");
				m_Towers		= new int[towers.length];
				for (int j = 0; j < m_Towers.length; j++) m_Towers[j] = Integer.parseInt(towers[j]);
			}
			else if (Tag.equals("huts")) {
				//Get tower
				String[] Huts	= Utilities.split(Value, ";");
				m_Huts			= new int[Huts.length];
				for (int j = 0; j < m_Huts.length; j++) m_Huts[j] = Integer.parseInt(Huts[j]);
			}
            else if (Tag.equals("path")) {
            	String points[] = Utilities.split(Value, ";");
            	m_PathX = new int[points.length];
            	m_PathY = new int[points.length];
            	
            	for(int j=0; j<points.length; ++j){
            		String point[] = Utilities.split(points[j], ",");
            		m_PathX[j] = Integer.parseInt(point[0]);
            		m_PathY[j] = Integer.parseInt(point[1]);
            	}

				//Get finish position
				m_FinishX = m_PathX[m_PathX.length - 1];
				m_FinishY = m_PathY[m_PathY.length - 1];
            }
            else if (Tag.equals("waves")) {
            	for (int j = 0; j <  ((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().size(); j++)
            		m_Waves.addElement(new Wave((XmlNode)((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().elementAt(j)));
            } else if (Tag.equals("stories")) {
				//Find the one with proper language
				XmlNode Child = (XmlNode)xmlNode.getChildren().elementAt(i);
            	for (int j = 0; j <  Child.getChildren().size(); j++) {
					//If story, check language
					if (((XmlNode)Child.getChildren().elementAt(j)).getNodeName().equals("story")) {
						if (((XmlNode)Child.getChildren().elementAt(j)).getAttribute("language").equals(StringManager.instance().getTag())) {
							//Get dialogs
							for (int k = 0; k < ((XmlNode)Child.getChildren().elementAt(j)).getChildren().size(); k++)
								m_Dialogs.addElement(new Dialog((XmlNode)((XmlNode)Child.getChildren().elementAt(j)).getChildren().elementAt(k)));
						}
					}
				}
			} else if (Tag.equals("goal")) {
				//For each children
				for (int j = 0; j < ((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().size(); j++) {
					//Get tag and value
					Tag		= ((XmlNode)((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().elementAt(j)).getNodeName();
					Value	= ((XmlNode)((XmlNode)((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().elementAt(j)).getChildren().elementAt(0)).getNodeValue();

					//Get value
					if (Tag.equals("gold"))			m_GoldGoal = Integer.parseInt(Value);
					else if (Tag.equals("time"))	m_TimeGoal = (long) (Float.parseFloat(Value) * 1000);
					else if (Tag.equals("tower")) {
						//Reset
						for (int k = 0; k < m_TowerGoal.length; k++) m_TowerGoal[k] = -1;

						//Split
						String[] TowerGoals = Utilities.split(Value, ";");
						for (int k = 0; k < TowerGoals.length; k++) {
							//Split again
							String[] TowerGoal = Utilities.split(TowerGoals[k], ":");

							//Read
							int Index	= Integer.parseInt(TowerGoal[0]);
							int Goal	= Integer.parseInt(TowerGoal[1]);

							//Check index
							if (Index >= 1 && Index < m_TowerGoal.length) m_TowerGoal[Index] = Goal;
						}
					}
				}
			} else if (!Utilities.getBool(Utilities.TUTORIAL_RMS, false) && Tag.equals("tutorials")) {
				//For each children
				for (int j = 0; j < ((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().size(); j++) {
					//Get node
					XmlNode Child = (XmlNode)((XmlNode)xmlNode.getChildren().elementAt(i)).getChildren().elementAt(j);
					
					//If tutorial
					if (Child.getNodeName().equals("tutorial")) m_Tutorials.addElement(new Tutorial(Child));
				}
			}
        }
		
        //Create map
        if (Set != null && Map != null) m_Map = new Map(Map, Set);
	}

	//Accessors
	public Map getMap()					{	return m_Map;					}
	public int getGold()				{	return m_StartGold;				}
    public int getLife()				{	return m_StartLife;				}
	public int getStartX()				{	return m_StartX;				}
	public int getStartY()				{	return m_StartY;				}
	public int getFinishX()				{	return m_FinishX;				}
	public int getFinishY()				{	return m_FinishY;				}
	public int getGoldGoal()			{	return m_GoldGoal;				}
	public long getTimeLimit()			{	return m_TimeGoal;				}
	public int[] getTowerGoal()			{	return m_TowerGoal;				}
    public int getWaveLength()          {   return m_Waves.size();			}
	public int[] getPathX()				{	return m_PathX;					}
	public int[] getPathY()				{	return m_PathY;					}
	public int[] getAvailableHuts()		{	return m_Huts;					}
	public int[] getAvailableTowers()	{	return m_Towers;				}
	public boolean hasTutorial()		{	return !m_Tutorials.isEmpty();	}

	public Wave getWave(int index) {
		//Check index
		if (index < 0)					return null;
		if (index >= m_Waves.size())	return null;

		//Return a wave
		return (Wave) m_Waves.elementAt(index);
	}

	public Dialog getDialog(int wave) {
		//Initial
		int i			= 0;
		Dialog Selected = null;

		//While not found
		while (i < m_Dialogs.size() && Selected == null) {
			//Get wave if wave is the same
			if (((Dialog)m_Dialogs.elementAt(i)).getWave() == wave) Selected = (Dialog) m_Dialogs.elementAt(i);

			//next
			i++;
		}

		if(Selected != null)
			Selected.loadCharacterImg();

		//Return the selected dialog
		return Selected;
	}
	
	public Tutorial getTutorial(int id) {
		//Get tutorial
		int i			= 0;
		Tutorial Result = null;
		

		//While not found
		while (i < m_Tutorials.size() && Result == null) {
			if (((Tutorial)m_Tutorials.elementAt(i)).getID() == id) Result = (Tutorial)m_Tutorials.elementAt(i); 

			//next
			i++;
		}
		
		//Return
		return Result;
	}

	//Data
	protected int		m_Index;
	protected Vector	m_Waves;
	protected int[]		m_Huts;
	protected int[]		m_Towers;
	protected Vector	m_Dialogs;
	protected Vector	m_Tutorials;
	protected int		m_StartGold;
    protected int       m_StartLife;

	//Goal
	protected long	m_TimeGoal;
	protected int	m_GoldGoal;
	protected int[]	m_TowerGoal;

	//Pathing
	protected int	m_StartX;
	protected int	m_StartY;
	protected int	m_FinishX;
	protected int	m_FinishY;
	protected int[] m_PathX;	//path
	protected int[]	m_PathY;	//path

	//Entities
	protected Map m_Map;
}
